package com.config;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.stereotype.Controller;

/**
 * 对 {@link EnableMethodSecurity} 的简要拆解测试
 */
@Configuration
public class MethodInterceptorConfig {



    @Bean
    public AuthorizationManagerBeforeMethodInterceptor authorizationManagerBeforeMethodInterceptor(){

        Pointcut pointcut = new AnnotationMatchingPointcut(Controller.class,PreAuthorize.class,true);

        AuthorizationManagerBeforeMethodInterceptor result = new AuthorizationManagerBeforeMethodInterceptor(
                pointcut,
                authorizationManagerForPreAuthorize()
        );

        return result;
    }

    /**
     * 这里是以 CGLib controller 方法代理的方式实现的 授权控制
     * 也可以配合 {@link AuthorizationFilter} 来使用 过滤器来进行授权控制，但是具体的灵活性太差（不能读取controller上的注解）
     * @return
     */
    @Bean
    public AuthorizationManager<MethodInvocation> authorizationManagerForPreAuthorize(){
        return new PreAuthorizeAuthorizationManager();
    }
}
